//
//  CCMeshBase.cpp
//  ShadowMapping
//
//  Created by Daniel Corleone on 5/6/14.
//  Copyright (c) 2014年 iCloverStudio. All rights reserved.
//

#include "CCMeshBase.h"
#include <cstring>
#include "PlatformFeatures.h"

BECO_NAMESPACE_BEGIN

Mesh::Mesh(const String& name)
: Node(eMesh, name)
, verticesBuffer(0)
, indicesBuffer(0)
, colorBuffer(0)
, numOfIndices(-1)
{
    rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
}

Mesh::Mesh(Node* parent, const String& name)
: Node(eMesh, parent, name)
, verticesBuffer(0)
, indicesBuffer(0)
, colorBuffer(0)
, numOfIndices(-1)
{
    rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
}

Mesh::~Mesh() {
    numOfIndices = -1;
    SAFE_DELETE_ARRAY(indicesBuffer);
    SAFE_DELETE_ARRAY(verticesBuffer);
    SAFE_DELETE_ARRAY(colorBuffer);
}

void
Mesh::Update(const Real timeInterval)
{
    Node::Update(timeInterval);
    return;
}

void
Mesh::Render(const Real timeInterval)
{
    if (numOfIndices <= 0)
        return;
    
//    // Counter-clockwise winding.
//    glFrontFace(GL_CW);
//    // Enable face culling.
//    glEnable(GL_CULL_FACE);
//    // What faces to remove with the face culling.
//    glCullFace(GL_BACK);
    
    // Enabled the vertices buffer for writing and
    //to be used during
    // rendering.
    glEnableClientState(GL_VERTEX_ARRAY);
    // Specifies the location and data format
    //of an array of vertex
    // coordinates to use when rendering.
    glVertexPointer(3, GL_FLOAT, 0, verticesBuffer);
    // Set flat color
    glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
    // Smooth color
    if (colorBuffer != 0) {
        // Enable the color array buffer to be
        //used during rendering.
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(4, GL_FLOAT, 0, colorBuffer);
    }
    
//    glTranslatef(x, y, z);
//    glRotatef(rx, 1, 0, 0);
//    glRotatef(ry, 0, 1, 0);
//    glRotatef(rz, 0, 0, 1);
    
    // Point out the where the color buffer is.
    glDrawElements(GL_TRIANGLES, numOfIndices, GL_UNSIGNED_INT, indicesBuffer);
    // Disable the vertices buffer.
    glDisableClientState(GL_VERTEX_ARRAY);
    // Disable face culling.
//    glDisable(GL_CULL_FACE);
    
    return;
}

void Mesh::setVertices(Real *vertices, const Int32 length) {
    // a float is 4 Bytes, therefore
    //we multiply the number if
    // vertices with 4.
    SAFE_DELETE_ARRAY(verticesBuffer);
    
    verticesBuffer = new Real[sizeof(Real) * length];
    ::memcpy(verticesBuffer, vertices, sizeof(Real) * length);
    
    return;
}

void Mesh::setIndices(Int32 *indices, const Int32 length) {
    // short is 2 Bytes, therefore we multiply
    //the number if
    // vertices with 2.
    SAFE_DELETE_ARRAY(indicesBuffer);
    
	indicesBuffer = new Int32[sizeof(Int32) * length];
	::memcpy((void*)indicesBuffer, indices, sizeof(Int32) * length);
    
    numOfIndices = length;
    
    return;
}

void Mesh::setColor(Real red, Real green,
                    Real blue, Real alpha) {
    // Setting the flat color.
    rgba[0] = red;
    rgba[1] = green;
    rgba[2] = blue;
    rgba[3] = alpha;
    
    return;
}

void Mesh::setColors(Real *colors, const Int32 length) {
    // float has 4 Bytes.
    SAFE_DELETE_ARRAY(colorBuffer);
    
    colorBuffer = new Real[sizeof(Real) * length];
    ::memcpy((void*)colorBuffer, colors, sizeof(Real) * length);
    
    return;
}

BECO_NAMESPACE_END
